package com.ccctop.crowd.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ccctop.crowd.api.MySQLRemoteService;
import com.ccctop.crowd.api.RedisRemoteService;
import com.ccctop.crowd.constant.CrowdConstant;
import com.ccctop.crowd.entity.po.MemberPO;
import com.ccctop.crowd.entity.vo.MemberLoginVO;
import com.ccctop.crowd.entity.vo.MemberVO;
import com.ccctop.crowd.entity.vo.MyCreateProjectVo;
import com.ccctop.crowd.exception.BizCodeEnum;
import com.ccctop.crowd.util.CrowdUtil;
import com.ccctop.crowd.util.ResultEntity;
import com.ccctop.crowd.util.SmsConponent;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@Controller
public class MemberHandler {
    @Autowired
    private RedisRemoteService redisRemoteService;
    @Autowired
    private MySQLRemoteService mySQLRemoteService;
    @Autowired
    SmsConponent smsConponent;
    @Autowired
    HttpSession httpSession;

    @RequestMapping("/member/my/crowd")
    public String mycrowd(RedirectAttributesModelMap map) {
        //如果没有登录，则转入到登录界面
        Object member = httpSession.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
        if (member==null){
            //未登录
            return "member-reg";
        }
        return "member-crowd";
    }

    @RequestMapping("/member/my/crowd/modelAttr")
    public String mycrowd(@RequestParam(CrowdConstant.MY_CREATE_PROJECTS)String myCreateProjectVos,ModelMap modelMap) {
        //如果没有登录，则转入到登录界面
        Object member = httpSession.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
        if (member==null){
            //未登录
            return "member-reg";
        }
        List<MyCreateProjectVo> projectVos = JSON.parseObject(myCreateProjectVos, new TypeReference<List<MyCreateProjectVo>>() {
        });
        System.out.println(projectVos);
        modelMap.addAttribute(CrowdConstant.MY_CREATE_PROJECTS,projectVos);
        return "member-crowd";
    }

    @RequestMapping("/auth/member/logout")
    public String logout(HttpSession httpSession) {
        httpSession.invalidate();
        return "redirect:http://localhost:81/index.html";
    }

    @RequestMapping("/auth/member/do/login")
    public String login(@RequestParam("loginacct") String loginacct,
                        @RequestParam("userpswd") String userpswd,
                        @RequestParam(value = "url",required = false) String url,
                        ModelMap modelMap,
                        HttpSession httpSession) {
        // 1.调用远程接口根据登录账号查询MemberPO对象
        ResultEntity<MemberPO> resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginacct);
        if (ResultEntity.FAILED.equals(resultEntity.getResult())) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
            return "member-login";
        }
        MemberPO memberPO = resultEntity.getData();
        if (memberPO == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        // 2.比较密码
        String userpswdDataBase = memberPO.getUserpswd();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matchesResult = bCryptPasswordEncoder.matches(userpswd, userpswdDataBase);
        if (!matchesResult) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        // 3.创建MemberLoginVO对象存入Session域
        MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
        httpSession.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER, memberLoginVO);

        if (url!=null&&!url.equals(""))
            return "redirect:"+url;
        else
            return "redirect:http://localhost:81/auth/member/to/center/page";
    }

    @RequestMapping("/auth/do/member/register")
    public String register(MemberVO memberVO, ModelMap modelMap) {
        // 1.获取用户输入的手机号
        String phoneNum = memberVO.getPhone();
        // 2.拼redis中存储验证码的key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        // 3.从redis读取key对应的value
        ResultEntity<String> resultEntity = redisRemoteService.getRedisStringValueByKeyRemote(key);
        // 4.查询操作是否有效
        String result = resultEntity.getResult();
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
            return "member-reg";
        }
        String redisCode = resultEntity.getData();
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
            return "member-reg";
        }
        // 5.如果能够到value则比较表单的验证码和redis的验证码
        String formCode = memberVO.getCode();
        if (!Objects.equals(formCode, redisCode)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";
        }
        // 6.如果验证码一致，则从redis删除
        redisRemoteService.removeRedisKeyRemote(key);
        // 7.执行密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String userpswd = memberVO.getUserpswd();
        String encode = passwordEncoder.encode(userpswd);
        memberVO.setUserpswd(encode);
        // 8.执行保存
        // 创建空的MemberPO对象
        MemberPO memberPO = new MemberPO();
        // 复制属性
        BeanUtils.copyProperties(memberVO, memberPO);
        // 调用远程方法
        ResultEntity<String> saveMemberResultEntity = mySQLRemoteService.saveMember(memberPO);
        if (ResultEntity.FAILED.equals(saveMemberResultEntity)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMemberResultEntity.getMessage());
            return "member-reg";
        }
        return "redirect:http://localhost:81/auth/member/to/login/page";
    }

    @ResponseBody
    @RequestMapping(value = "/auth/member/send/short/message.json", method = RequestMethod.POST)
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) throws RuntimeException {
        //1. 验证手机号码格式是否正确
        boolean matches = Pattern.matches("^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$", phoneNum);
        if (matches == false) {
            return ResultEntity.failed(BizCodeEnum.PHONE_NUMBER_ERROR.getMsg());
        }
        //2. 验证该手机号码是否为已注册用户的手机
        ResultEntity<MemberPO> memberByPhone = mySQLRemoteService.getMemberByPhone(phoneNum);
        MemberPO member = memberByPhone.getData();
        if (member != null) {
            //手机号码不对应任何用户的手机
            return ResultEntity.failed(BizCodeEnum.PHONE_NUMBER_USED.getMsg());
        }
        // 3.发送验证码到手机
        String uuid = String.valueOf(System.currentTimeMillis());
        String code = uuid.substring(uuid.length()-4, uuid.length());
        //TODO 验证码已经调通，但是没有购买api，所以查看验证码请到redis控制台查看
//        smsConponent.sendPhoneCode(phoneNum, code);
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        System.out.println("验证码为："+code);
        ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
        if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
            return ResultEntity.successWithoutData();
        } else {
            return saveCodeResultEntity;
        }
    }
}
